As explained in the Overview section, tramp connects to the remote host and talks to the shell it finds there. Of course, when you log in, the shell executes its init files. Suppose your init file requires you to enter the birth date of your mother; clearly tramp does not know this and hence fails to log you in to that host.
There are different possible strategies for pursuing this problem. One strategy is to enable tramp to deal with all possible situations. This is a losing battle, since it is not possible to deal with all situations. The other strategy is to require you to set up the remote host such that it behaves like tramp expects. This might be inconvenient because you have to invest a lot of effort into shell setup before you can begin to use tramp.
The package, therefore, pursues a combined approach. It tries to figure out some of the more common setups, and only requires you to avoid really exotic stuff. For example, it looks through a list of directories to find some programs on the remote host. And also, it knows that it is not obvious how to check whether a file exists, and therefore it tries different possibilities. (On some hosts and shells, the command test -e does the trick, on some hosts the shell builtin doesn't work but the program /usr/bin/test -e or /bin/test -e works. And on still other hosts, ls -d is the right way to do this.)
Below you find a discussion of a few things that tramp does not deal with, and that you therefore have to set up correctly.
shell-prompt-pattern has to
be set correctly to recognize the shell prompt on the remote
host.
Note that tramp requires the match
for shell-prompt-pattern to be at the end of the
buffer. Many people have something like the following as the
value for the variable: "^[^>$][>$] *".
Now suppose your shell prompt is a <b> c $
. In this case, tramp recognizes the
> character as the end of the prompt, but it
is not at the end of the buffer.
shell-prompt-pattern, to match
prompts from the remote shell. This second variable exists
because the prompt from the remote shell might be different
from the prompt from a local shell — after all, the whole
point of tramp is to log in to remote
hosts as a different user. The default value of
tramp-shell-prompt-pattern is the same as the
default value of shell-prompt-pattern, which is
reported to work well in many circumstances.tramp-password-prompt-regexp handles the detection of such requests for English environments. When you use another localization of your (local or remote) host, you might need to adapt this. Example:
(setq
tramp-password-prompt-regexp
(concat
"^.*"
(regexp-opt
'("passphrase" "Passphrase"
;; English
"password" "Password"
;; Deutsch
"passwort" "Passwort"
;; Français
"mot de passe" "Mot de passe") t)
".*:? *"))
In parallel, it might also be necessary to adapt
tramp-wrong-passwd-regexp.
TERM environment variable, it will be set to
dumb when connecting.
The variable
tramp-terminal-type can be used to change this
value to dumb.
The
other approach is to teach tramp
about these questions. See the variable
tramp-actions-before-shell. Example:
(defconst my-tramp-prompt-regexp
(concat (regexp-opt '("Enter the birth date of your mother:") t)
"\\s-*")
"Regular expression matching my login prompt question.")
(defun my-tramp-action (proc vec)
"Enter \"19000101\" in order to give a correct answer."
(save-window-excursion
(with-current-buffer (tramp-get-connection-buffer vec)
(tramp-message vec 6 "\n%s" (buffer-string))
(tramp-send-string vec "19000101"))))
(add-to-list 'tramp-actions-before-shell
'(my-tramp-prompt-regexp my-tramp-action))
FRUMPLE in your shell environment, then this
might cause trouble. Maybe rename the variable to
FRUMPLE_DIR or the like.
This weird effect was actually reported by a tramp user!
Now, some people have a login shell which is not
/bin/sh but a Bourne-ish shell such as bash or
ksh. Some of these people might put their shell setup into
the files ~/.shrc or
~/.profile. This way,
it is possible for non-Bourne constructs to end up in those
files. Then, exec
/bin/sh might cause the Bourne shell to barf on
those constructs.
As an example, imagine somebody putting export FOO=bar into the file ~/.profile. The standard Bourne shell does not understand this syntax and will emit a syntax error when it reaches this line.
Another example is the tilde (~) character,
say when adding ~/bin
to PATH. Many Bourne shells will not expand this
character, and since there is usually no directory whose name
consists of the single character tilde, strange things will
happen.
What can you do about this?
Well, one possibility is to make sure that everything in ~/.shrc and ~/.profile on all remote hosts is Bourne-compatible. In the above example, instead of export FOO=bar, you might use FOO=bar; export FOO instead.
The other possibility is to put your non-Bourne shell setup into some other files. For example, bash reads the file ~/.bash_profile instead of ~/.profile, if the former exists. So bash aficionados just rename their ~/.profile to ~/.bash_profile on all remote hosts, and Bob's your uncle.
The tramp developers would like to
circumvent this problem, so if you have an idea about it,
please tell us. However, we are afraid it is not that simple:
before saying exec
/bin/sh, tramp does not
know which kind of shell it might be talking to. It could be
a Bourne-ish shell like ksh or bash, or it could be a csh
derivative like tcsh, or it could be zsh, or even rc. If the
shell is Bourne-ish already, then it might be prudent to omit
the exec /bin/sh
step. But how to find out if the shell is
Bourne-ish?
You can redefine the shell prompt by checking the
environment variable INSIDE_EMACS, which is set
by tramp, in your startup script
~/.emacs_SHELLNAME.
SHELLNAME might be the string bash
or similar, in case of doubt you could set it the environment
variable ESHELL in your .emacs:
(setenv "ESHELL" "bash")
Your file ~/.emacs_SHELLNAME could contain code like
# Reset the prompt for remote Tramp shells.
if [ "${INSIDE_EMACS/*tramp*/tramp}" == "tramp" ] ; then
PS1="[\u@\h \w]$ "
fi